package com.kika.obwiki.websocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;

/**
 * WebSocket服务器
 * 处理WebSocket连接和消息推送
 */
@Component
@ServerEndpoint("/ws/{token}") // 客户端连接地址
public class WebSocketServer {

  private static final Logger LOG = LoggerFactory.getLogger(WebSocketServer.class);

  /**
   * 每个客户端一个token
   */
  private String token = "";

  /**
   * 放置所有连接
   */
  private static HashMap<String, Session> map = new HashMap<>();

  /**
   * 连接成功
   */
  @OnOpen
  public void onOpen(Session session, @PathParam("token") String token) {
    map.put(token, session);
    this.token = token;
    LOG.info("有新连接：token：{}，session id：{}，当前连接数：{}", token, session.getId(), map.size());
  }

  /**
   * 连接关闭
   */
  @OnClose
  public void onClose(Session session) {
    map.remove(this.token);
    LOG.info("连接关闭，token：{}，session id：{}！当前连接数：{}", this.token, session.getId(), map.size());
  }

  /**
   * 收到消息
   */
  @OnMessage
  public void onMessage(String message, Session session) {
    LOG.info("收到消息：{}，内容：{}", token, message);
  }

  /**
   * 连接错误
   */
  @OnError
  public void onError(Session session, Throwable error) {
    LOG.error("发生错误", error);
  }

  /**
   * 群发消息
   */
  public void sendInfo(String message) {
    for (String token : map.keySet()) {
      Session session = map.get(token);
      try {
        session.getBasicRemote().sendText(message);
      } catch (IOException e) {
        LOG.error("推送消息失败：{}，内容：{}", token, message);
      }
      LOG.info("推送消息：{}，内容：{}", token, message);
    }
  }

  /**
   * 发送消息给指定用户
   */
  public void sendMessageToUser(String token, String message) {
    Session session = map.get(token);
    if (session != null && session.isOpen()) {
      try {
        session.getBasicRemote().sendText(message);
        LOG.info("推送消息给用户：{}，内容：{}", token, message);
      } catch (IOException e) {
        LOG.error("推送消息给用户失败：{}，内容：{}", token, message);
      }
    } else {
      LOG.warn("用户{}不在线或连接已关闭", token);
    }
  }

  /**
   * 获取当前连接数
   */
  public static int getConnectionCount() {
    return map.size();
  }

  /**
   * 检查用户是否在线
   */
  public static boolean isUserOnline(String token) {
    Session session = map.get(token);
    return session != null && session.isOpen();
  }
}